package abc.generator;

import abc.base.BaseEntity;
import abc.base.BaseGenerator;
import abc.config.DatasourceConfigure;
import abc.config.MybatisPlusAutoFillConfig;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class MyBatisPlusGenerator extends BaseGenerator {

    @Autowired
    DatasourceConfigure datasourceConfigure;

    public MyBatisPlusGenerator() {
        super();
    }

    public MyBatisPlusGenerator(DatasourceConfigure datasourceConfigure) {
        super(datasourceConfigure, new MybatisPlusAutoFillConfig());
    }

    /**
     * 数据源配置
     */
    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
            .Builder("jdbc:mysql://127.0.0.1:3306/abc","root","123456");


    /**
     * 生成Api代码
     */
    @Override
    protected void build(DataSourceConfig.Builder datasourceConfigBuilder, Map<String, Map<String, Object>> tableMap, List<Map<String, Object>> columns, String datasourceName, String dbname) throws Exception {
        FastAutoGenerator.create(datasourceConfigBuilder)
                // 全局配置
                .globalConfig((scanner, builder) -> {
                    String root = scanner.apply("请输入生成项目根目录：");
                    while(new File(System.getProperty("user.dir") + File.separator + root).exists()) {
                        root = scanner.apply(root+"已存在，请重新输入生成项目根目录：");
                    }
                    builder
                            //.author(scanner.apply("请输入作者名称："))
                            .author("linlurui")
                            .dateType(DateType.TIME_PACK)
                            //.fileOverride()
                            .enableSwagger()
                            //.disableOpenDir()
                            .commentDate("yyyy-MM-dd")
                            .outputDir(System.getProperty("user.dir") + File.separator + root);
                })
                // 包配置
                .packageConfig((scanner, builder) ->
                        builder.parent("abc")
                        .moduleName(scanner.apply("请输入主包名称："))
                        .entity("entity")
                        .service("service")
                        .serviceImpl("service.impl")
                        .mapper("mapper")
                        .xml("mapper.xml")
                        .controller("controller")
                        .other("other")
                )
                // 策略配置
                //.strategyConfig((scanner, builder) -> builder.addInclude(scanner.apply("请输入表名，多个表名用,隔开")))
                .strategyConfig(builder -> setStrategyConfig(builder, tableMap))
                .templateConfig(builder -> {
                    builder
                            .entity("/templates/entity.java")
                            .service("/templates/service.java")
                            .serviceImpl("/templates/serviceImpl.java")
                            .mapper("/templates/mapper.java")
                            .xml("/templates/mapper.xml")
                            .controller("/templates/controller.java");
                })
                /**模板引擎配置**/
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }


    private void setStrategyConfig(StrategyConfig.Builder builder,  Map<String, Map<String, Object>> tableMap) {
        builder.addInclude(tableMap.keySet().toArray(new String[]{})) // 设置需要生成的表名
                .addTablePrefix("t_", "c_") // 设置过滤表前缀
                .enableCapitalMode()
                .entityBuilder()
                    .superClass(BaseEntity.class)
                    .addSuperEntityColumns("id")
                    .disableSerialVersionUID()
                    .enableChainModel()
                    .enableLombok()
                    .enableRemoveIsPrefix()
                    .enableTableFieldAnnotation()
                    .enableActiveRecord()
                    .versionColumnName("version")
                    .versionPropertyName("version")
                    .logicDeleteColumnName("deleted")
                    .logicDeletePropertyName("deleted")
                    .naming(NamingStrategy.no_change)
                    .columnNaming(NamingStrategy.underline_to_camel)
                    .addSuperEntityColumns("id", "create_by", "create_on", "modify_by", "modify_on")
                    .addIgnoreColumns("age")
                    .addTableFills(new Column("create_time", FieldFill.INSERT))
                    .addTableFills(new Property("update_time", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Column("created_time", FieldFill.INSERT))
                    .addTableFills(new Property("updated_time", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Column("create_on", FieldFill.INSERT))
                    .addTableFills(new Property("update_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Column("created_on", FieldFill.INSERT))
                    .addTableFills(new Property("updated_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("modify_time", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("modify_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("remove_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("removed_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("delete_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("deleted_on", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("remove_time", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("removed_time", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("delete_time", FieldFill.INSERT_UPDATE))
                    .addTableFills(new Property("deleted_time", FieldFill.INSERT_UPDATE))
                    .idType(IdType.AUTO)
                    .formatFileName("%sEntity")
                .controllerBuilder()
                    //.superClass(BaseController.class)
                    .enableHyphenStyle()
                    .enableRestStyle()
                    .formatFileName("%sController")
                .mapperBuilder()
                    //.superClass(BaseMapper.class)
                    .enableMapperAnnotation()
                    .enableBaseResultMap()
                    .enableBaseColumnList()
                    .formatMapperFileName("%sDao")
                    .formatXmlFileName("%sXml");
    }

}
